#include<iostream>  
#include<queue>  
#include <algorithm>
using namespace std;

int moves[6] = { 0,-1,0,1,0 };//四个方向  
char mp[15][15];//地图数组  

struct Node
{
	int px, py, bx, by; //人的位置，盒子位置
	Node(int x, int y, int bx, int by) 
		:px(x), py(y), bx(bx), by(by) {}
};
queue<Node>q; //状态队列
int st[15][15][15][15];//四维数组表示人和箱子的位置状态,开始全为0  
int sx, sy, bx, by, n, m;//分别表示当前人的位置，盒子的位置，终点位置，以及地图尺寸。  

//广度优先算法
int bfs_minPushBox()
{
	for (int i = 0; i < n; i++)//初始化人，箱子，终点的位置  
	{
		for (int j = 0; j < m; j++)
		{
			if (mp[i][j] == '*')
			{
				bx = i;
				by = j;
			}
			else if (mp[i][j] == 'X') {
				sx = i;
				sy = j;
			}
		}
	}
	st[sx][sy][bx][by] = 1;//起始状态位置设步数为1  
	Node tmp(sx, sy, bx, by);
	
	q.push(tmp);//初始状态入栈  

	auto bound = [&](int x, int y) -> bool { // 不越界且不在墙上
		return x >= 0 && x < n && y >= 0 && y < m && mp[x][y] != '#';
	};

	while (!q.empty()) //只要队列不为空就一直寻找  
	{
		tmp = q.front();//取出首元素  
		q.pop();//弹出  
		if(mp[tmp.bx][tmp.by]=='@')
			return st[tmp.px][tmp.py][tmp.bx][tmp.by] - 1;//如果箱子在终点，结束，返回步数  
		for (int i = 0; i < 4; i++)//四个方向开始搜索了  
		{
			//先更新人的位置  
			int px = tmp.px + moves[i];
			int py = tmp.py + moves[i + 1];
			if (!bound(px, py))
				continue;//如果这个位置非法，探寻其它方向  
			if (px == tmp.bx && py == tmp.by)//如果此时人的位置与箱子的位置重合，说明人应当推动了箱子  
			{
				if (!bound(tmp.bx + moves[i], tmp.by + moves[i + 1]))
					continue;//如果箱子移动的位置不合法，则重新探寻其它方向  
				st[px][py][tmp.bx + moves[i]][tmp.by + moves[i + 1]] =
					st[tmp.px][tmp.py][tmp.bx][tmp.by] + 1;//箱子推动，则人和箱子位置改变，记录新状态  
				q.push(Node(px, py, tmp.bx + moves[i], tmp.by + moves[i + 1]));//新状态入栈  

			}
			else//人没有推动箱子  
			{
				if (st[px][py][tmp.bx][tmp.by])//如果移动后的状态出现过，则重新搜索新方向  
					continue;
				st[px][py][tmp.bx][tmp.by] = st[tmp.px][tmp.py][tmp.bx][tmp.by] + 1;  
				q.push(Node(px, py, tmp.bx, tmp.by));//更新状态  
			}
		}
	}
	return -1;//如果所有位置都试过了，没有找到，说明不存在  
}

int main()
{
	cin >> n >> m;
	
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++)
		{
			cin >> mp[i][j];
		}
	}
	cout << bfs_minPushBox() << endl;

	return 0;
}
//
// 数据测试 
//5 4
//. @ # .
//.X # .
//.* . .
//# . # .
//. . . .

输出 10
